package cn.funeralobjects.urms.service.impl;

import cn.funeralobjects.common.jpa.service.CommonCloudCrudJpaService;
import cn.funeralobjects.common.repository.CommonCloudRepository;
import cn.funeralobjects.common.service.annotataion.CommonRollback;
import cn.funeralobjects.common.service.annotataion.CommonService;
import cn.funeralobjects.common.service.exception.DataConflictException;
import cn.funeralobjects.common.service.validate.DataCheck;
import cn.funeralobjects.urms.entity.ETagUserRes;
import cn.funeralobjects.urms.entity.ETagUserResPk;
import cn.funeralobjects.urms.entity.EUserRes;
import cn.funeralobjects.urms.model.UserRes;
import cn.funeralobjects.urms.repository.ETagUserResRepository;
import cn.funeralobjects.urms.repository.EUserResRepository;
import cn.funeralobjects.urms.service.UserResService;
import cn.funeralobjects.util.Assert;
import cn.funeralobjects.util.NumberUtils;
import cn.funeralobjects.util.annotation.ArgHasLength;
import cn.funeralobjects.util.annotation.ArgNotZero;
import cn.funeralobjects.util.annotation.AssertArg;

import javax.annotation.Resource;

/**
 * @author FuneralObjects
 * Create date: 2020/6/10 3:21 PM
 */
@CommonService
public class UserResServiceImpl implements UserResService, CommonCloudCrudJpaService<UserRes, EUserRes, Integer> {
    @Resource
    private EUserResRepository eUserResRepository;
    @Resource
    private ETagUserResRepository eTagUserResRepository;

    @Override
    public CommonCloudRepository<EUserRes, Integer> commonCloudRepository() {
        return eUserResRepository;
    }

    @AssertArg
    @Override
    public void checkConflict(@AssertArg UserRes userRes) throws DataConflictException {
        this.mustNotConflictByCode(userRes.getCode());
        DataCheck.conflictData(eUserResRepository.existsAllByResCodeAndUserCodeAndDelSalt(userRes.getResCode(), userRes.getUserCode(), getExistsDelSalt()),
                () -> createDataCode("resCode-userCode", userRes.getResCode() + "-" + userRes.getUserCode()));
        DataCheck.conflictData(eUserResRepository.existsAllByUserCodeAndNameAndDelSalt(userRes.getUserCode(), userRes.getName(), getExistsDelSalt()),
                () -> createDataCode("userCode-name", userRes.getUserCode() + "-" + userRes.getName()));
    }

    @Override
    public EUserRes toEntity(UserRes userRes) {
        EUserRes entity = new EUserRes();
        entity.setResCode(userRes.getResCode())
                .setUserCode(userRes.getUserCode())
                .setCode(userRes.getCode())
                .setName(userRes.getName());
        return entity;
    }

    @AssertArg
    @Override
    public void checkConflict(@AssertArg UserRes userRes, @ArgNotZero Integer withoutId) throws DataConflictException {
        this.mustNotConflictByCode(userRes.getCode());
        DataCheck.conflictData(eUserResRepository.existsAllByUserCodeAndNameAndDelSaltAndIdNot(userRes.getUserCode(), userRes.getName(), getExistsDelSalt(), withoutId),
                () -> createDataCode("userCode-name", userRes.getUserCode() + "-" + userRes.getName()));
    }

    @Override
    public void copyToEntity(UserRes sourceModify, EUserRes targetEntity) {
        targetEntity.setCode(sourceModify.getCode())
                .setName(sourceModify.getName());
    }

    @Override
    public boolean isValid(Integer id) {
        return NumberUtils.notZero(id);
    }

    @Override
    public void validateModify(UserRes userRes) {
        Assert.argAssert(userRes, "userRes");
    }

    @Override
    public Integer getExistsDelSalt() {
        return (Integer) eUserResRepository.getDefaultExistsDelSalt();
    }

    @CommonRollback
    @AssertArg
    @Override
    public void bindTag(@ArgNotZero Integer userResId, @ArgHasLength String tagTypeCode, @ArgHasLength String tagValueCode) {
        this.mustExistsById(userResId);
        eTagUserResRepository.save(new ETagUserRes().setPk(new ETagUserResPk().setTagValueCode(tagValueCode).setUserResId(userResId)).setTagTypeCode(tagTypeCode));
    }

    @CommonRollback
    @AssertArg
    @Override
    public void unbindTag(@ArgNotZero Integer userResId, @ArgHasLength String tagValueCode) {
        if (this.existsById(userResId)) {
            eTagUserResRepository.deleteById(new ETagUserResPk().setUserResId(userResId).setTagValueCode(tagValueCode));
        }
    }
}
